import { ElMessageBox } from "element-plus";
import { md5 } from "js-md5";
import { useRoute, useRouter } from "vue-router";

export const useVerifyRouter = (): KRotuer => {
  const router = useRouter();
  const route = useRoute();
  return new KRotuer(router, route);
};

export class KRotuer {
  router: any;
  route: any;

  constructor(router: any, route: any) {
    this.router = router;
    this.route = route;
  }

  get query(): any {
    return this.route?.query;
  }

  get params(): any {
    return this.route?.params;
  }

  makeObjectVerifyKey(obj: any): string {
    const kvs: string[] = [];
    for (const key in Object.keys(obj ?? {})) {
      if (obj?.hasOwnProperty(key)) {
        const val = obj[key];
        if (typeof val === "object") {
          // Is array
          if (Array.isArray(val)) {
            kvs.push(`${key}=${val.join(",")}`);
          } else {
            kvs.push(`${key}=${this.makeObjectVerifyKey(val)}`);
          }
        } else {
          kvs.push(`${key}=${val}`);
        }
      }
    }
    const sortKvs = kvs.sort().join("|");
    return md5(sortKvs);
  }

  verifyQuery(query: any): boolean {
    if (!query) return;
    const vk = query?._vk;
    if (!vk) return false;
    const origin = Object.assign({}, query);
    delete origin._vk;

    return this.makeObjectVerifyKey(origin) === vk;
  }

  verifyRoute(): boolean {
    return this.verifyQuery(this.route.query);
  }

  async validate(mustQuery?: string[]): Promise<any> {
    let isPass = this.verifyRoute();
    if (isPass && mustQuery) {
      for (const key of mustQuery) {
        if (!this.query[key]) {
          isPass = false;
          break;
        }
      }
    }
    return new Promise((resolve, reject) => {
      if (!isPass) {
        ElMessageBox.alert("路由信息有误,请返回重进!!", {
          title: "提示"
        }).then(() => {
          this.back();
          reject();
        });
      } else {
        resolve("ok");
      }
    });
  }

  push(req: { name?: string; path?: string; params?: any; query?: any }) {
    this.router?.push({
      name: req.name,
      path: req.path,
      params: req.params,
      query: {
        ...req.query,
        _vk: this.makeObjectVerifyKey(req.query)
      }
    });
  }

  back() {
    this.router?.back();
  }

  replace(req: { name?: string; path?: string; params?: any; query?: any }) {
    this.router?.replace({
      name: req.name,
      path: req.path,
      params: req.params,
      query: {
        ...req.query,
        _vk: this.makeObjectVerifyKey(req.query)
      }
    });
  }
}
